﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

using LastFmClient;

using System.Threading;

using TranscoderSharp;

namespace Enceladus___Audio_Transcoder
{
    public partial class Form1 : Form
    {
        Transcoder TranscoderObject = new Transcoder();
        Thread t;

        BindingSource bs = new BindingSource();
        IEnumerable<object> displayObject;

        public Form1()
        {
            InitializeComponent();
            dataGridView_AudioFiles.AutoGenerateColumns = false;

            /*
             * Just for testing 
             */
            textBox_OutputFolder.Text = @"k:\test mp3\";
            
            /*TranscoderObject.LoadAudioFiles(@"e:\sorted\");
            bs.DataSource = TranscoderObject;
            dataGridView_AudioFiles.DataSource = bs;*/

            //Artist artist = new Artist("oasis");
            //Track track = new Track("wonderwall", "oasis").TopSimilarTrack.Track;

            TranscoderObject.TranscodingStarted += new EventHandler(TranscoderObject_TranscodingStarted);
            TranscoderObject.AudioFileProcessed += new Transcoder.AudioFileProcessedEventHandler(TranscoderObject_AudioFileProcessed);
            TranscoderObject.TranscodingFinished += new EventHandler(TranscoderObject_TranscodingFinished);
        }

        void TranscoderObject_TranscodingFinished(object sender, EventArgs e)
        {
            this.Invoke((MethodInvoker)delegate
            {
                string complete = string.Format("Encoding complete.  Encoded {0} " +
                    "Skipped {1} Errored {2}", TranscoderObject.Encoded, TranscoderObject.Skipped,
                    TranscoderObject.Errors);

                MessageBox.Show(this, complete, "Encoding Complete.", MessageBoxButtons.OK);
                button_EncodeFiles.Enabled = true;
            });
        }

        void TranscoderObject_AudioFileProcessed(object sender, TranscoderEventArgs e)
        {
            this.Invoke((MethodInvoker)delegate
                {
                    toolStripStatusLabel.Text = e.AudioFile.ToString() + " " + e.AudioFile.Status.ToString();
                    toolStripStatusLabel_time.Text = GetTimeRemaing(TranscoderObject.Processed, TranscoderObject.Count);
                    toolStripStatusLabel_counter.Text =
                        TranscoderObject.Processed.ToString() + " of " + TranscoderObject.Count.ToString();
                    progressBar_Encoding.Value = TranscoderObject.Processed;
                    dataGridView_AudioFiles.Refresh();
                });
        }

        void TranscoderObject_TranscodingStarted(object sender, EventArgs e)
        {
            this.Invoke((MethodInvoker)delegate
            {
                toolStripStatusLabel.Text = "Encoding begun";
                progressBar_Encoding.Maximum = TranscoderObject.Count;
                progressBar_Encoding.Value = 0;
            });
        }

        private void button_OutputFolder_Click(object sender, EventArgs e)
        {
            // Show the FolderBrowserDialog.
            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                textBox_OutputFolder.Text = folderBrowserDialog1.SelectedPath;
            }
        }


        BackgroundWorker bg = new BackgroundWorker();
        private void button_AddFolder_Click(object sender, EventArgs e)
        {
            string folder;

            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                folder = folderBrowserDialog1.SelectedPath;

                bg.DoWork += new DoWorkEventHandler(bg_doWork);
                bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

                progressBar_Encoding.Style = ProgressBarStyle.Marquee;
                progressBar_Encoding.MarqueeAnimationSpeed = 100;
                bg.RunWorkerAsync(folder);


                //bs.DataSource = TranscoderObject.OrderBy(p => p.Title);
                //dataGridView_AudioFiles.DataSource = bs;
                //toolStripStatusLabel.Text = TranscoderObject.Count.ToString() + " audio files loaded";
            }
        }

        public void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar_Encoding.Style = ProgressBarStyle.Blocks;
            progressBar_Encoding.MarqueeAnimationSpeed = 0;


            dataGridView_AudioFiles.DataSource = bs;
            toolStripStatusLabel.Text = TranscoderObject.Count.ToString() + " audio files loaded";
        }



        public void bg_doWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                dataGridView_AudioFiles.AutoGenerateColumns = false;
                TranscoderObject.LoadAudioFiles(e.Argument.ToString());

                var result =
                    from af in TranscoderObject
                    //orderby af.Artist
                    select new { Title = af.Title, Artist = af.Artist, Album = af.Album, Status = af.Status, Size = af.SizeMB };

                //displayObject = result;

                //bs.DataSource = TranscoderObject.OrderBy(p => p.FilePath).Select;
                //bs.DataSource = result;
                bs.DataSource = TranscoderObject;

                
            }
            catch (Exception ex)
            {

            }
        }

        private void button_ConfigureLame_Click(object sender, EventArgs e)
        {
            Configure cfg = new Configure();
            cfg.ShowDialog();
        }

        private void button_EncodeFiles_Click(object sender, EventArgs e)
        {
            button_EncodeFiles.Enabled = false;

            LameConfig lc = LameConfig.Load();
            lc.OutputDirectory = textBox_OutputFolder.Text;
            lc.OutputFormatPath = textBox_OutputFormatPath.Text;
            lc.ApplyMp3Gain = checkBox_ApplyMp3Gain.Checked;
            lc.OverwriteExisting = checkBox_OverwriteFiles.Checked;
            TranscoderObject.ConfigObject = lc;

            ThreadStart ts = new ThreadStart(TranscoderObject.Transcode);
            t = new Thread(ts);
            t.IsBackground = true;
            t.Start();

            /*
            progressBar_Encoding.Value = 0;
            progressBar_Encoding.Maximum = TranscoderObject.Count;

            LameConfig lc = LameConfig.Load();

            TimeSpan TimeTaken = new TimeSpan();

            foreach (AudioFile af in TranscoderObject)
            {               
                Application.DoEvents();
                int n = progressBar_Encoding.Value + 1;

                lc.ApplyMp3Gain = checkBox_ApplyMp3Gain.Checked;
                af.ConfigObject = lc;
                af.ConfigObject.OutputDirectory = textBox_OutputFolder.Text;

                // do a quick check to see if output file already exists and if we should overwrite it
                //if (Transcoder.OutputFileExists(af) && !checkBox_OverwriteFiles.Checked)
                //    continue;

                try
                {

                    toolStripStatusLabel.Text = "Encoding " + af.ToString();
                    toolStripStatusLabel_counter.Text = n.ToString() + " of " + TranscoderObject.Count.ToString();

                    lc.ApplyMp3Gain = checkBox_ApplyMp3Gain.Checked;
                    af.ConfigObject = lc;
                    af.ConfigObject.OutputDirectory = textBox_OutputFolder.Text;

                    if (TranscoderObject.IsTrackFromVariousArtistsAlbum(af))
                    {
                        af.ConfigObject.OutputFormatPath = @"{ALBUM}\{ALBUM} - {TRACKNUMBER} - {ARTIST} - {TITLE}";
                    }
                    else
                    {
                        af.ConfigObject.OutputFormatPath = @"{ARTIST}\{ALBUM}\{ARTIST} - {ALBUM} - {TRACKNUMBER} - {TITLE}";
                    }

                    af.ConfigObject.OverwriteExisting = checkBox_OverwriteFiles.Checked;

                    ParameterizedThreadStart pts = new ParameterizedThreadStart(Transcoder.TranscodeFile);
                    t = new Thread(pts);
                    t.IsBackground = true;
                    t.Start(af);

                    //t.Join();
                    //Transcoder.TranscodeFile(af);
                    while (t.IsAlive)
                    {
                        Thread.Sleep(1000);
                        //Thread.
                        Application.DoEvents();
                    }
                    //int n = TranscoderObject.FindIndex(p => p.FilePath == af.FilePath);


                    toolStripStatusLabel_time.Text = GetTimeRemaing(TimeTaken, n, TranscoderObject.Count);

                    //bs.DataSource = TranscoderObject;
                    //bs.ResetBindings(false);
                   //dataGridView_AudioFiles.Refresh();
                    ///dataGridView_AudioFiles.Update();

                }
                catch (Exception ex)
                {
                    //System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient("smtp.gmail.com");
                    //smtpClient.Port = 465;
                    //smtpClient.EnableSsl = true;
                    //smtpClient.Credentials = new System.Net.NetworkCredential("andy.burchill", "embrace2");
                    //smtpClient.Send("andy.burchill@gmail.com",
                    //    "andy.burchill@gmail.com",
                    //    "[EXCEPTION] " + af.Title,
                    //    af.ToString() + "\r\n" + ex.ToString() + "\r\n" + af.FilePath + af.GetMp3ValidationResult());

                    try
                    {

                        System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient("relay.clara.net");
                        //smtpClient.Port = 465;
                        //smtpClient.EnableSsl = true;
                        smtpClient.Credentials = new System.Net.NetworkCredential("eps@epscylonb.com", "oasis12");
                        smtpClient.Send("Encledus@epscylonb.com",
                            "andy.burchill@gmail.com",
                            "[EXCEPTION] " + af.Title,
                            af.ToString() + "\r\n" + ex.ToString() + "\r\n" +
                            af.FilePath + "\r\n" + af.GetMp3ValidationResult());
                    }

                    catch
                    {

                    }
                    //MessageBox.Show(ex.ToString(), "An error occured.", MessageBoxButtons.OK);
                }

                progressBar_Encoding.PerformStep();

                dataGridView_AudioFiles.Refresh();
                //dataGridView_AudioFiles.Update();
            }

            string complete = string.Format("Encoding complete.  Encoded {0} " +
                "Skipped {1} Errored {2}", TranscoderObject.Encoded, TranscoderObject.Skipped,
                TranscoderObject.Errors);

            MessageBox.Show(complete, "Encoding Complete.", MessageBoxButtons.OK);
            button_EncodeFiles.Enabled = true;
             */
        }

        private string GetTimeRemaing(int progress, int totala)
        {
            if (TranscoderObject.Encoded == 0 || TranscoderObject.TotalBytesEncoded == 0)
                return "Unknown";

            TimeSpan Remaining = TranscoderObject.RemainingTime;

            return String.Format("{0:00}:{1:00}:{2:00}",
            Remaining.Days, Remaining.Hours, Remaining.Minutes);


            //double ratio = TimeTaken.TotalMinutes / TranscoderObject.Encoded;
            //int MinutesRemaining = Convert.ToInt32(ratio * TranscoderObject.Unencoded);

            //TimeSpan timeRemaining = new TimeSpan(0, MinutesRemaining, 0);

            //double ratio = TimeTaken.TotalMinutes / progress;

            //int nRemaining = total - progress;

            //int TotalMinutes = Convert.ToInt32(ratio * total);

            //int MinutesRemaining = TotalMinutes - Convert.ToInt32(ratio * progress);

            //TimeSpan timeRemaining = new TimeSpan(0, MinutesRemaining, 0);

            //return String.Format("{0:00}:{1:00}:{2:00}",
            //timeRemaining.Days, timeRemaining.Hours, timeRemaining.Minutes);

        }

        private void button_AddFiles_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            //dialog.Filter =
            //   "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            ////dialog.InitialDirectory = initialDirectory;
            //dialog.Title = "Select a text file";

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                TranscoderObject.Add(new AudioFile(dialog.FileName));
                BindingSource bs = new BindingSource();
                bs.DataSource = TranscoderObject;
                dataGridView_AudioFiles.DataSource = bs;
            }

        }

        private void button_Clear_Click(object sender, EventArgs e)
        {
            TranscoderObject.Clear();
            BindingSource bs = new BindingSource();
            bs.DataSource = TranscoderObject;
            dataGridView_AudioFiles.DataSource = bs;
        }

        private void button_Pause_Click(object sender, EventArgs e)
        {
            if (button_Pause.Text == "Pause")
                button_Pause.Text = "Paused";
            if (button_Pause.Text == "Paused")
                button_Pause.Text = "Pause";
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (t != null && t.IsAlive)
                t.Abort();
        }
    }
}
